#include <stdio.h>
#include <stdlib.h>
/* here for getopt() */
//#define _POSIX_SOURCE
#include <unistd.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>
#include <string.h>

#include "parser/language_scanner.h"
#include "parser/ypl_parser.h"

void display_help(char* self, FILE* file_no);

int main(int argc, char **argv) {
	char opt_c=0,/*-c "1+2+3" - calculate "inline" */
	     opt_f=0,/* -f expressions.txt - evaluate the file, line by line */
	     opt_h=0;/* -h - display help */
	char *c_expr=NULL;/*the expression to calc via -c parameter*/
	char *file_path=NULL;/*the file path specified via opt_f*/
	int input=0;/*the file specified via opt_f*/

	int c;
	scanner_state *state;
	AST_node *ast_tree;

	while(-1 != (c = getopt(argc,argv,"c:f:h"))) {
		switch(c) {
			case 'c':
				opt_c = 1;
				c_expr = optarg;
				break;
			case 'f':
				opt_f = 1;
				file_path = optarg;
				break;
			case 'h':
				opt_h = 1;
				break;
			case '?':
				fprintf(stderr,"Invalid option '%c'\n",optopt);
				display_help(argv[0],stderr);
				return EXIT_FAILURE;
				break;

		}
	}
	
	if(opt_h) {
		display_help(argv[0],stdout);
		return EXIT_SUCCESS;
	}
	if(!(opt_c || opt_f)) {
		display_help(argv[0],stderr);
		return EXIT_FAILURE;
	}
	state = malloc(sizeof(scanner_state));
	if(!state) {
		fprintf(stderr,"not enough memory in main()\n");
		return EXIT_FAILURE;
	}
	if(opt_f) {
		printf("processing file \"%s\"\n",file_path);
		SCANNER_INIT(*state);
		input = open(file_path,O_RDONLY);
		struct stat sb;
		fstat(input,&sb);

		opt_c = 1;
		c_expr = mmap(NULL,sb.st_size,PROT_READ,MAP_PRIVATE,input,0);
		write(STDOUT_FILENO,c_expr,sb.st_size);
	}
	if(opt_c) {
		printf("\nprocessing inline expression \"%s\"\n",c_expr);
		SCANNER_INIT(*state);
		SCANNER_STATE_SET_STRING(*state,c_expr);
	}
	parse_language(state);
	return EXIT_SUCCESS;
}


void display_help(char* self, FILE* file_no) {
	fprintf(file_no,
		"%s with one or more of these parameters:\n"
		"\t-c \"<math expression>\"\n"
		"\t-f file\n"
		"\t-h display this help\n",
		self
	);
}
